package org.korifey.ffbdd.api.op;

import org.korifey.ffbdd.api.INode;

public class OpCacheKey {
	
	//Operation code
	protected int opcode;
	
	public int opcode() {
		return opcode;
	}
	
	
	
	private OpCacheKey(int code) {
		super();
		this.opcode = code;
	}



	public static class Binary extends OpCacheKey {
		protected INode left;
		protected INode right;		
		
		public INode left() {
			return left;
		}
		
		public INode right() {
			return right;
		}
		
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((left == null) ? 0 : left.hashCode());
			result = prime * result + opcode;
			result = prime * result + ((right == null) ? 0 : right.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Binary other = (Binary) obj;
			if (left == null) {
				if (other.left != null)
					return false;
			} else if (!left.equals(other.left))
				return false;
			if (opcode != other.opcode)
				return false;
			if (right == null) {
				if (other.right != null)
					return false;
			} else if (!right.equals(other.right))
				return false;
			return true;
		}

		public Binary(INode left, INode right, int opcode) {
			super(opcode);
			this.left = left;
			this.right = right;			
		}
	}

	
	
	public static class Unary extends OpCacheKey {
		protected INode node;		
		
		public INode node() {
			return node;
		}
		
		public Unary(INode node, int opcode) {
			super(opcode);
			this.node = node;			
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((node == null) ? 0 : node.hashCode());
			result = prime * result + opcode;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Unary other = (Unary) obj;
			if (node == null) {
				if (other.node != null)
					return false;
			} else if (!node.equals(other.node))
				return false;
			if (opcode != other.opcode)
				return false;
			return true;
		}
	}
}
